﻿package Network 
{
	import com.junkbyte.console.Cc;
	
	import Common.Constants;
	import Common.ImageInfo;
	import Common.Room;
	import Common.XMLUtils;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.xml.XMLDocument;
	import flash.xml.XMLNode;
	import flash.xml.XMLNodeType;
	
	/**
	 * ...
	 * @author Serg de Adelantado
	 */
	[Event(name = 'complete', type = "flash.events.Event")]
	[Event(name = 'connect', type = "flash.events.Event")]
	[Event(name = 'login_error', type = "Network.XMLErrorEvent")]
	[Event(name = 'parser_error', type = "Network.XMLErrorEvent")]	
	public class XMLLoader extends EventDispatcher 
	{
		private const XML_URL:String = Constants.MAIN_XML;
		
		private var FLoader:URLLoader;
		private var FRooms:Vector.<Room>;
		private var FImages:Vector.<ImageInfo>;
		private var FMainID:int;
		
		public function XMLLoader() 
		{
			FLoader = new URLLoader();
			FLoader.addEventListener(Event.COMPLETE, OnXMLLoaded);
			FLoader.addEventListener(IOErrorEvent.IO_ERROR, OnIOError);
			FLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, OnSecurityError);
			FRooms = new Vector.<Room>;
			FImages = new Vector.<ImageInfo>;
		}		
		
		public function Load(AID:String = '-1'):void 
		{	
			var vParams:String = '?obj_id=' + AID + '&rand=' + new Date().fullYearUTC.toString();			
			var vRequest:URLRequest = new URLRequest(XML_URL + vParams);
			vRequest.method = URLRequestMethod.POST;
			FLoader.load(vRequest);
			dispatchEvent(new Event(Event.CONNECT));
		}
		
		private function OnXMLLoaded(e:Event):void 
		{
			FLoader.removeEventListener(Event.COMPLETE, OnXMLLoaded);
			FLoader.removeEventListener(IOErrorEvent.IO_ERROR, OnIOError);
			FLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, OnSecurityError);
			
			var vData:XML = XML(e.target.data);
			Cc.logch('XML', '\n' + vData);
			var vDoc:XMLDocument = new XMLDocument();
			vDoc.ignoreWhite = true;
			vDoc.parseXML(vData);
			var vRoot:XMLNode = vDoc.firstChild;
			
			if (vRoot.firstChild.nodeName == 'error')
			{
				var vCode:int = int(vRoot.firstChild.attributes['code']);				
				switch (vCode)
				{
					case 1:
						dispatchEvent(new XMLErrorEvent(XMLErrorEvent.LOGIN_ERROR));
					break;
					default:
					break;
				}
			}
			else
			{
				var vSetingsNode:XMLNode = XMLUtils.Node(vRoot, 'settings');				
				var vRoomsNode:XMLNode = XMLUtils.Node(vRoot, 'rooms');
				var vImages:Vector.<XMLNode> = XMLUtils.NodesByName(vRoot, 'images');				
				FMainID = int(vImages[0].attributes['object_id']);	
				FRooms.push(new Room(FMainID.toString(), 'Главный альбом'));
				if (vSetingsNode)
				{
					var vSize:XMLNode = XMLUtils.Node(vSetingsNode, 'Size');
					Constants.IMAGE_SIZE = int(vSize.attributes['value']);					
				}
				if (vRoomsNode)
				{
					var vRooms:Vector.<XMLNode> = XMLUtils.NodesByName(vRoomsNode, 'room');
					for each(var vRoomNode:XMLNode in vRooms)
					{
						var vRoom:Room = new Room(vRoomNode.attributes['id'], vRoomNode.attributes['name']);
						vRoom.Rooms = vRoomNode.attributes['total'];
						vRoom.Apartments = vRoomNode.attributes['rooms'];
						vRoom.InRoom = vRoomNode.attributes['vnomere'];
						vRoom.About = vRoomNode.attributes['about'];						
						FRooms.push(vRoom);
					}
				}
				for each(var vImageNode:XMLNode in vImages)
				{					
					ProcessImages(vImageNode, int(vImageNode.attributes['object_id']));
				}
				dispatchEvent(new Event(Event.COMPLETE));
			}						
		}
		
		private function ProcessImages(AImages:XMLNode, AObjectID:int):void 
		{
			var vImages:Vector.<XMLNode> = XMLUtils.NodesByName(AImages, 'image');			
			var vImage:ImageInfo;			
			for (var i in vImages)
			{
				vImage = new ImageInfo();				
				vImage.ID = int(vImages[i].attributes['id']);				
				vImage.ObjectID = AObjectID;				
				vImage.Description = vImages[i].attributes['description'];		
				vImage.IsPublic = int(vImages[i].attributes['published']) == 0;
				vImage.ToDelete = int(vImages[i].attributes['to_del']) > 0;
				vImage.Order = int(vImages[i].attributes['ord']);
				vImage.IsAttachedToRoom = IsRoom(AObjectID);
				FImages.push(vImage);
			}			
		}
		
		public function AddRoom(ARoom:Room):void
		{
			FRooms.push(ARoom);
		}
		
		public function DeleteRoom(ARoom:Room):void
		{
			var vIndex:int = FRooms.indexOf(ARoom);
			if (vIndex > -1)
				FRooms.splice(vIndex, 1);
		}
		
		public function IsRoom(AID:int):Boolean
		{	
			if (AID == FMainID)
				return false;
			for (var i in FRooms)			
				if (FRooms[i].ID == AID)
					return true;			
			return false;
		}
		
		public function ImageAt(AIndex:int):ImageInfo
		{
			return FImages[AIndex];
		}
		
		public function get ImagesCount():int
		{
			return FImages.length;
		}
		
		public function get Rooms():Vector.<Room>
		{
			return FRooms
		}
		
		public function get MainID():int 
		{
			return FMainID;
		}
		
		public function ImagesByRoom(ARoomID:int):Vector.<ImageInfo>
		{
			var vResult:Vector.<ImageInfo> = new Vector.<ImageInfo>;
			for (var i in FImages)
				if (FImages[i].ObjectID == ARoomID)
					vResult.push(FImages[i]);
			return vResult;
		}
		
		//{ Error handlers 
		
		private function OnIOError(e:IOErrorEvent):void 
		{
			Cc.errorch('XMLLoader', 'IO error: ' + e.text);
			dispatchEvent(new XMLErrorEvent(XMLErrorEvent.PARSER_ERROR));
		}
		
		private function OnSecurityError(e:SecurityErrorEvent):void 
		{
			Cc.errorch('XMLLoader', 'Security error: ' + e.text);
			dispatchEvent(new XMLErrorEvent(XMLErrorEvent.PARSER_ERROR));
		}
		
		//} endregion
		// End of Error handlers		
	}
}